package com.jianbo.proxy.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;

public class FileUtil {

    public static byte[] readBytes(InputStream in) throws Exception {
        // 文件流的长度是可预见的，此时直接读取效率更高
        final byte[] result;
        try {
            final int available = in.available();
            result = new byte[available];
            final int readLength = in.read(result);
            if (readLength != available) {
                throw new RuntimeException("readLength != available");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result;
	}

    public static byte[] readBytesFast(String path) {
        FileInputStream in = null;
        try {
            File file = new File(path);
            if(!file.exists()) {
                return null;
            }
            in = new FileInputStream(file);
            // return IoReadUtil.toByteArray(in);
            return readBytes(in);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            close(in);
        }
    }

    private static void close(FileInputStream in) {
        try {
            if(in != null) {
                in.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static byte[] readBytes(String path) {
        try {
            File file = new File(path);
            if(!file.exists()) {
                return null;
            }
            FileInputStream in = new FileInputStream(file);
            return IoUtil.read(in);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static InputStream readStream(String propFile) throws FileNotFoundException {
        File file = new File(propFile);
        FileInputStream in = new FileInputStream(file);
        return in;
    }

    public static String fileType(String path) {
        int pos = path.lastIndexOf(".");
        if(pos == -1) {
            return null;
        }
        return path.substring(pos + 1, path.length());
    }

    public static String readString(String file) {
        try {
            byte[] bytes = readBytes(file);
            return ByteUtil.toStr(bytes);
        } catch (RuntimeException e) {
            Debug.info(file);
            throw e;
        }
    }

    public static boolean exist(String path) {
        File file = new File(path);
        return file.exists();
    }
    
    // 遍历指定目录文件
    public static List<String> traverseFiles(String folder) {
        List<File> files = FileTraversal.traverseFiles(new File(folder));
        List<String> fileNames = new ArrayList<>();
        for(File file : files) {
            fileNames.add( file.getPath() );
        }
        return fileNames;
    }

    public static void saveFile(String filePath, byte[] content) {
        try {
            File file = new File(filePath);
            touch(file);
            FileOutputStream fos = new FileOutputStream(file, false); 
            fos.write(content);
            fos.flush();
            fos.close();

        } catch (Exception e) {
			throw new RuntimeException("保存文件内容失败", e);
        }
    }

    /**
	 * 创建文件及其父目录，如果这个文件存在，直接返回这个文件<br>
	 * 此方法不对File对象类型做判断，如果File不存在，无法判断其类型
	 *
	 * @param file 文件对象
	 * @return 文件，若路径为null，返回null
	 * @throws RuntimeException IO异常
	 */
	public static File touch(File file) throws RuntimeException {
		if (null == file) {
			return null;
		}
		if (false == file.exists()) {
			mkParentDirs(file);
			try {
				//noinspection ResultOfMethodCallIgnored
				file.createNewFile();
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		return file;
	}

    /**
	 * 创建所给文件或目录的父目录
	 *
	 * @param file 文件或目录
	 * @return 父目录
	 */
	public static File mkParentDirs(File file) {
		final File parentFile = file.getParentFile();
		if (null != parentFile && false == parentFile.exists()) {
			//noinspection ResultOfMethodCallIgnored
			parentFile.mkdirs();
		}
		return parentFile;
	}

    public static boolean exists(String fileName) {
        File file = new File(fileName);
        return file.exists();
    }
}
